import { _decorator, animation, Animation, AnimationClip, Component, Node, Sprite, SpriteFrame, UITransform } from 'cc';
import { TILE_HEIGHT, TILE_WIDTH } from '../Tile/TileManager';
import ResourceManager from '../../Runtime/ResourceManager';
import { CONTROLLER_ENUM, DIRECTION_ENUM, DIRECTION_ORDER_ENUM, ENTITY_STATE_ENUM, ENTITY_TYPE_ENUM, EVENT_ENUM, PARAMS_NAME_ENUM } from '../../Enums';
import EventManager from '../../Runtime/EventManager';
import { PlayerStateMachine } from './PlayerStateMachine';
import { EntityManager } from '../../Base/EntityManager';
import DataManager from '../../Runtime/DataManager';
const { ccclass, property } = _decorator;



@ccclass('PlayerManager')
export class PlayerManager extends EntityManager {

    targetX: number = 0;

    targetY: number = 0

    private readonly speed = 1 / 10

    isMoving: boolean = false

    async init() {
        this.fsm = this.addComponent(PlayerStateMachine)
        await this.fsm.init()

        super.init({
            x: 2,
            y: 8,
            type: ENTITY_TYPE_ENUM.PLAYER,
            direction: DIRECTION_ENUM.TOP,
            state: ENTITY_STATE_ENUM.IDLE
        })

        this.targetX = this.x
        this.targetY = this.y

        this.direction = DIRECTION_ENUM.TOP

        this.state = ENTITY_STATE_ENUM.IDLE

        EventManager.Instance.on(EVENT_ENUM.PLAYER_CTRL, this.inputHandle, this)
        EventManager.Instance.on(EVENT_ENUM.ATTACK_PLAYER, this.onDead, this)
    }

    update() {
        this.updateXY()
        super.update()
    }

    updateXY() {
        if (this.targetX < this.x) {
            this.x -= this.speed
        } else if (this.targetX > this.x) {
            this.x += this.speed
        }

        //逼近targetY
        if (this.targetY < this.y) {
            this.y -= this.speed
        } else if (this.targetY > this.y) {
            this.y += this.speed
        }

        //两者近似就触发结束
        if (Math.abs(this.targetX - this.x) < 0.01 && Math.abs(this.targetY - this.y) < 0.01 && this.isMoving) {
            this.x = this.targetX
            this.y = this.targetY
            this.isMoving = false
            EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
        }

    }

    onDead(type: ENTITY_STATE_ENUM) {
        this.state = type
    }

    inputHandle(inputDirection: CONTROLLER_ENUM) {
        if (this.isMoving) {
            return
        }
        if (this.state === ENTITY_STATE_ENUM.AIRDEATH || this.state === ENTITY_STATE_ENUM.DEATH || this.state === ENTITY_STATE_ENUM.ATTACK) {
            return
        }
        const id  = this.willAttack(inputDirection)
        if (id) {
            EventManager.Instance.emit(EVENT_ENUM.ATTACK_ENEMY, id)
            return
        }
        if (this.willBlock(inputDirection)) {
            return
        }
        this.move(inputDirection)
    }

    willBlock(inputDirection: CONTROLLER_ENUM) {
        const { targetX: x, targetY: y, direction } = this
        const { tileInfo } = DataManager.Instance
        if (inputDirection === CONTROLLER_ENUM.TOP) {
            const playerNextY = y - 1;
            if (playerNextY < 0) {
                this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                return true;
            }

            const playerTile = tileInfo[x][playerNextY]
            const weaponTile = tileInfo[x][playerNextY - 1]
            if (playerTile && playerTile.moveable && (!weaponTile || weaponTile.turnable)) {

            } else {
                this.state = ENTITY_STATE_ENUM.BLOCKFRONT
                return true;
            }

        } else if (inputDirection === CONTROLLER_ENUM.TURNLEFT) {
            let nextX
            let nextY
            if (direction === DIRECTION_ENUM.TOP) {
                nextX = x - 1
                nextY = y - 1
            } else if (direction === DIRECTION_ENUM.BOTTOM) {
                nextX = x + 1
                nextY = y + 1
            } else if (direction === DIRECTION_ENUM.LEFT) {
                nextX = x - 1
                nextY = y + 1
            } else if (direction === DIRECTION_ENUM.RIGHT) {
                nextX = x + 1
                nextY = y - 1
            }

            if (
                (!tileInfo[x][nextY] || tileInfo[x][nextY].turnable) &&
                (!tileInfo[nextX][y] || tileInfo[nextX][y].turnable) &&
                (!tileInfo[nextX][nextY] || tileInfo[nextX][nextY].turnable)
            ) {

            } else {
                this.state = ENTITY_STATE_ENUM.BLOCKTURNLEFT
                return true;
            }
        }
        return false;
    }

    willAttack(type: CONTROLLER_ENUM) {
        const enimies = DataManager.Instance.enimies.filter(enemy => enemy.state !== ENTITY_STATE_ENUM.DEATH)
        for (let i = 0; i < enimies.length; i++) {
            const { x: enemyX, y: enemyY, id: enemyId } = enimies[i]
            if (type === CONTROLLER_ENUM.TOP && 
                this.direction == DIRECTION_ENUM.TOP && 
                enemyX === this.x &&
                enemyY === this.targetY - 2) {
                this.state = ENTITY_STATE_ENUM.ATTACK
                return enemyId
            }
        }
        return ''
    }

    move(inputDirection: CONTROLLER_ENUM) {
        console.info('tile_info', DataManager.Instance.tileInfo)
        // EventManager.Instance.emit(EVENT_ENUM.RECORD_STEP)
        if (inputDirection === CONTROLLER_ENUM.TOP) {
            this.targetY -= 1
            this.isMoving = true
            //   this.showSmoke(DIRECTION_ENUM.TOP)
        } else if (inputDirection === CONTROLLER_ENUM.BOTTOM) {
            this.targetY += 1
            this.isMoving = true
            //   this.showSmoke(DIRECTION_ENUM.BOTTOM)
        } else if (inputDirection === CONTROLLER_ENUM.LEFT) {
            this.targetX -= 1
            this.isMoving = true
            //   this.showSmoke(DIRECTION_ENUM.LEFT)
        } else if (inputDirection === CONTROLLER_ENUM.RIGHT) {
            this.targetX += 1
            this.isMoving = true
            //   this.showSmoke(DIRECTION_ENUM.RIGHT)
        } else if (inputDirection === CONTROLLER_ENUM.TURNLEFT) {
            if (this.direction === DIRECTION_ENUM.TOP) {
                this.direction = DIRECTION_ENUM.LEFT
            } else if (this.direction === DIRECTION_ENUM.BOTTOM) {
                this.direction = DIRECTION_ENUM.RIGHT
            } else if (this.direction === DIRECTION_ENUM.LEFT) {
                this.direction = DIRECTION_ENUM.BOTTOM
            } else if (this.direction === DIRECTION_ENUM.RIGHT) {
                this.direction = DIRECTION_ENUM.TOP
            }
            this.state = ENTITY_STATE_ENUM.TURNLEFT
            EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
        } else if (inputDirection === CONTROLLER_ENUM.TURNRIGHT) {
            if (this.direction === DIRECTION_ENUM.TOP) {
                this.direction = DIRECTION_ENUM.RIGHT
            } else if (this.direction === DIRECTION_ENUM.BOTTOM) {
                this.direction = DIRECTION_ENUM.LEFT
            } else if (this.direction === DIRECTION_ENUM.LEFT) {
                this.direction = DIRECTION_ENUM.TOP
            } else if (this.direction === DIRECTION_ENUM.RIGHT) {
                this.direction = DIRECTION_ENUM.BOTTOM
            }
            this.state = ENTITY_STATE_ENUM.TURNRIGHT
            EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
        }
    }


}